package com.efun.framework.beetlsql;

import org.beetl.sql.core.Interceptor;
import org.beetl.sql.core.JPA2NameConversion;
import org.beetl.sql.core.NameConversion;
import org.beetl.sql.core.UnderlinedNameConversion;
import org.beetl.sql.core.db.DBStyle;
import org.beetl.sql.core.db.MySqlStyle;
import org.beetl.sql.ext.DebugInterceptor;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * daosuffix不会生效
 * @author  kinven on 17/7/9.
 */
@ConfigurationProperties("beetlsql")
public class BeetlSqlProperties {
    public static final String SQL_MANAGER_FACTORY_BEAN_NAME = "sqlManagerFactoryBean";
    public static final String DAO_SUFFIX = "Dao";
    public static final String MASTE_DATASOURCE_NAME="masteDatasource";
    public static final String SLAVE_DATASOURCE_NAME="slaveDatasource";

    private static final String CONFIG_DECRYPT="config.decrypt";
    private static final String CONFIG_DECRYPT_KEY="config.decrypt.key";
    private static final String DEFAULT_CONFIG_FILTERS="config,log4j2";
    private static final String DEFAULT_URL="jdbc:mysql://localhost:3306/test";
    private static final int DEFAULT_MAXACTIVIE = 30;
    private static final String DEFAULT_JDBC_DRIVER="com.mysql.jdbc.Driver";
    private static final String DEFAULT_DB_STYLE_NAME="mySqlStyle";
    private static final String DEFAULT_NAME_CONVERSTION_NAME="underlinedNameConversion";
    private static final String DEFAULT_SQL_PATH="/sql";

    private String sqlPath=DEFAULT_SQL_PATH;// 模板跟目录,默认使用sql文件夹

    private String nameConversion=DEFAULT_NAME_CONVERSTION_NAME;// 数据库和javapojo的映射关系

    private String dbStyle = DEFAULT_DB_STYLE_NAME;
    private String interceptors = "";

    private DruidSetting druid;

    public String getSqlPath() {
        return sqlPath;
    }

    public void setSqlPath(String sqlPath) {
        this.sqlPath = sqlPath;
    }

    public String getNameConversion() {
        return nameConversion;
    }

    public void setNameConversion(String nameConversion) {
        this.nameConversion = nameConversion;
    }

    public String getDbStyle() {
        return dbStyle;
    }

    public void setDbStyle(String dbStyle) {
        this.dbStyle = dbStyle;
    }

    public String getInterceptors() {
        return interceptors;
    }

    public void setInterceptors(String interceptors) {
        this.interceptors = interceptors;
    }

    public DruidSetting getDruid() {
        return druid;
    }

    public void setDruid(DruidSetting druid) {
        this.druid = druid;
    }

    public static class DruidSetting{

        private DataSourceSetting maste = new DataSourceSetting(MASTE_DATASOURCE_NAME);
        private List<DataSourceSetting> slave = new LinkedList<DataSourceSetting>();
        private ConnectionSetting conn = new ConnectionSetting();

        public ConnectionSetting getConn() {
            return conn;
        }

        public void setConn(ConnectionSetting conn) {
            this.conn = conn;
        }

        public DataSourceSetting getMaste() {
            return maste;
        }

        public void setMaste(DataSourceSetting maste) {
            this.maste = maste;
        }

        public List<DataSourceSetting> getSlave() {
            return slave;
        }

        public void setSlave(List<DataSourceSetting> slave) {
            this.slave = slave;
        }

        public String getSlaveNames(){
            Set<String> names = new LinkedHashSet<String>();
            for(DataSourceSetting setting : slave){
                names.add(setting.getName());
            }
            return StringUtils.collectionToCommaDelimitedString(names);
        }
    }

    public static class ConnectionSetting {
        private boolean encrypt = false;
        private String publicKey;
        private String privateKey;
        private String filters = DEFAULT_CONFIG_FILTERS;

        public boolean isEncrypt() {
            return encrypt;
        }

        public void setEncrypt(boolean encrypt) {
            this.encrypt = encrypt;
        }

        public String getPublicKey() {
            return publicKey;
        }

        public void setPublicKey(String publicKey) {
            this.publicKey = publicKey;
        }

        public String getPrivateKey() {
            return privateKey;
        }

        public void setPrivateKey(String privateKey) {
            this.privateKey = privateKey;
        }

        public String getFilters() {
            return filters;
        }

        public void setFilters(String filters) {
            this.filters = filters;
        }

        public Properties toProperties(){
            Properties p = new Properties();
            if(isEncrypt() && null != publicKey) {
                p.setProperty(CONFIG_DECRYPT,"true");
                p.setProperty(CONFIG_DECRYPT_KEY,publicKey);
            }
            return p;
        }
    }

    public static class DataSourceSetting {
        private String url = DEFAULT_URL;
        private String username;
        private String password;
        private int maxactive = DEFAULT_MAXACTIVIE;
        private String driverclassname = DEFAULT_JDBC_DRIVER;
        private String name;

        public DataSourceSetting(){

        }

        public DataSourceSetting(String name){
            this.name = name;
        }

        public String getUrl() {
            return url;
        }

        public void setUrl(String url) {
            this.url = url;
        }

        public String getUsername() {
            return username;
        }

        public void setUsername(String username) {
            this.username = username;
        }

        public String getPassword() {
            return password;
        }

        public void setPassword(String password) {
            this.password = password;
        }

        public int getMaxActive() {
            return maxactive;
        }

        public void setMaxActive(int maxActive) {
            this.maxactive = maxActive;
        }

        public String getDriverClassName() {
            return driverclassname;
        }

        public void setDriverClassName(String driverClassName) {
            this.driverclassname = driverClassName;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }
    }
}
